package com.weilive.core.protocol.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.weilive.core.protocol.PacketCodec;
import com.weilive.core.protocol.PacketError;

public class JsonPacket {

	public Integer id;
	public Integer codec;
	public String type;
	public Object data;
	public PacketError error;

	public static JsonPacket decode(String text) throws Exception {
		if (text == null || text.length() == 0)
			return null;
		JSONObject object = JSONObject.parseObject(text, JSONObject.class);
		JsonPacket packet = new JsonPacket();
		packet.id = object.getInteger("id");
		packet.codec = object.getInteger("codec");
		packet.type = object.getString("type");
		if (packet.codec != null && PacketCodec.clientIsGZIP(packet.codec)) {
			packet.data = JSONObject.parseObject(PacketCodec.decode(packet.codec, object.getString("data")),
					JSONObject.class);
		} else {
			packet.data = object.getJSONObject("data");
		}
		JSONObject error = object.getJSONObject("error");
		if (error != null) {
			packet.error = new PacketError(error.getIntValue("code"), error.getString("message"));
		} else {
			packet.error = null;
		}
		return packet;
	}

	public String encode() throws Exception {
		JSONObject object = new JSONObject();
		if (id != null)
			object.put("id", id);
		if (type != null)
			object.put("type", type);
		if (error != null) {
			object.put("error", JSONObject.toJSON(error));
		} else if (codec != null && PacketCodec.serverIsGZIP(codec)) {
			object.put("codec", codec);
			object.put("data", PacketCodec.encode(codec, JSONObject.toJSONString(data)));
		} else {
			object.put("data", JSONObject.toJSON(data));
		}
		return object.toJSONString();
	}

	public JsonPacket() {

	}

	public JsonPacket(Object data) {
		setTypeData(data);
	}

	public JsonPacket(Integer codec, Object data) {
		setTypeData(data);
		this.codec = codec;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Integer getCodec() {
		return codec;
	}

	public void setCodec(Integer codec) {
		this.codec = codec;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public PacketError getError() {
		return error;
	}

	public void setError(PacketError error) {
		this.error = error;
	}

	public void setTypeData(Object data) {
		this.type = data.getClass().getSimpleName();
		this.data = data;
	}

	public <T> T getTypeData(Class<T> c) {
		if (error == null && data instanceof JSON) {
			return JSONObject.toJavaObject((JSON) data, c);
		}
		return null;
	}

	public String toString() {
		return JSONObject.toJSONString(this);
	}
}
